#ifndef _TAIIC_UART_SUM_H_
#define _TAIIC_UART_SUM_H_

#include <termios.h> // PPSIX 终端控制定义
#include "rk_debug.h"
#include "rk_defines.h"
#include <stdbool.h> // 使用stdbool.h来获得true和false的定义
#include <mutex>
#include <fstream>
#include <vector>
#include <queue>

#include <cstddef>
#include <cstdint>
#include <condition_variable>
#include <functional>
#include "server_socket.h"
#include <taiic_opencv.h>

using namespace std;
using namespace cv;

typedef unsigned char u8;
typedef unsigned int u32;

// 保存音频数据到PCM
void appendToPcmFile(const char *filename, uint8_t *data, unsigned int length);

// UART串口设置
#define SERIAL_PORT "/dev/ttyS4"
#define BAUD_RATE B921600 // 预定义的宏，表示921600bps的波特率
#define DATA_BITS 8
#define STOP_BITS 1

// 上传图像信息
#define SEND_IMG_WIDTH 112
#define SEND_IMG_HEIGHT 112
#define SEND_IMG_SIZE 18816   // 112*112*1.5
#define SEND_IMG_Y_SIZE 12544 // 112*112
#define SEND_PKG_CNT 19
#define SEND_PKG_CNT_Y 13
#define SEND_PKG_SIZE 1028
#define PER_PKG_IMG_SIZE 1024
#define SEND_PKG_SIZE_516 516
static char *first_lip_data_char = NULL;
static string first_lip_data_str;

#define AI_COUNT 112
#define PCM_SIZE_SOC 53280


// 上位机->耳机的数据接收回调定义
typedef void(tSppFrameDataCallback)(uint8_t keyValue); // spp数据回调
// 开启spp数据的回调
void taiic_spp_frame_data_callback(tSppFrameDataCallback spp_frame_data);

// ai数据回调定义
typedef void(tAiFrameDataCallback)(uint8_t *data, unsigned int len, unsigned short frame_num,uint8_t type); // ai数据回调
void taiic_ai_frame_data_callback(tAiFrameDataCallback ai_frame_data);

// 音频数据信息回调
typedef void (*AudioDataType)(unsigned int len, unsigned short frame_num);
void AudioDataCallBack(AudioDataType fp, unsigned int len, unsigned short frame_num);
void audioDataFunc(unsigned int len, unsigned short frame_num);

// 测试数据回调定义
typedef void(tTestFrameDataCallback)(uint8_t *data, unsigned short len);
void taiic_test_frame_data_callback(tTestFrameDataCallback test_frame_data);

// 唇图发送与模式上传相关
#define NORMAL_MODE 96 // 常规模式
#define LIP_MODE 97    // 特殊模式
static int current_mode_state = 0;
static int init_mode_value = 0; // 判断模式的初始状态，常规模式/特殊模式

static uint8_t first_img_data[SEND_IMG_SIZE] = {0}; // 18816
static uint8_t first_img_data_y[SEND_IMG_Y_SIZE] = {0};
static uint8_t per_pkg_data[PER_PKG_IMG_SIZE] = {0};  // 1024
static uint8_t send_pkg_data485[SEND_PKG_SIZE] = {0}; // 1028
/*------------ringBuffer-------------*/
class RingBuf_Taiic_U
{
private:
    unsigned int validLen;      // 已使用的数据长度
    uint8_t *pHead = NULL;      // 环形存储区的首地址
    uint8_t *pTail = NULL;      // 环形存储区的结尾地址
    uint8_t *pValid = NULL;     // 已使用的缓冲区的首地址
    uint8_t *pValidTail = NULL; // 已使用的缓冲区的尾地址
public:
    void initRingbuffer(void);
    int writeRingbuffer(uint8_t *buffer, int addLen);
    unsigned int readRingbuffer(uint8_t *buffer, unsigned int len);
    unsigned int getRingbufferValidLen(void);
    void releaseRingbuffer(void);
    long bufferSize;
};
#define RB_MAX_SIZE 512 * 1000
static RingBuf_Taiic_U serialData;
static int serial_fd = 0; // 串口驱动文件描述符

std::string toHex(uint8_t byte); // 将一个uint8_t转换为两个字符的16进制字符串
/*---------------------------------485------------------------------*/
#define UART_DEV_NAME "/dev/ttyS0"
void UART0_INIT(int fd);
void rs_send(const char *send_buf, int data_len); // 有线485唇图发送函数
void rs_send_uint8(uint8_t *send_buf, int data_len);
#define BUF_RECV_SIZE 1024 // 485 recv buf size
/*-----------audio frame analysis------------------*/
unsigned short calc_crc16(const uint8_t *buffer, unsigned int size, unsigned short crc);
unsigned short big_to_little_u16(void *data);
bool fileExists(const char *filename);
long getFileSize(const char *filename);
void int_to_hex_array(int value, uint8_t *array);
/*------------------------serial config----------------*/
int serial_send_function(void *data, unsigned short data_len);
// frame analysis
#define FRAME_FLAG_INDEX 0
#define FRAME_FROM_INDEX 1
#define FRAME_TO_INDEX 2
#define FRAME_COMMAND_ID_INDEX 3
#define FRAME_DATA_LENGTH_INDEX 4
#define FRAME_DATA_START_ADDR_INDEX (4 + 2)
#define FRAME_HEADER_LENGTH 6
#define FRAME_CHECKSUM_INDEX(x) (x + FRAME_DATA_START_ADDR_INDEX)
#define FRAME_CHECK_DATA_LENGTH(x) (x + FRAME_HEADER_LENGTH)
#define FRAME_TOTAL_LENGTH(x) (x + FRAME_HEADER_LENGTH + 2) // 2表示2个校验位crcH/crcL
#define FRAME_FLAG 0xFE
#define CHECKSUM_INIT_VALUE 0xA1B2
#define FRAME_BUFFER_LENGTH_MAX 65536

typedef enum
{
    parse_error_cmd = 0x00,           // 指令解析错误指令
    inquire_firmware_info_cmd = 0x01, // 固件版本信息查询指令
    battery_status_notify_cmd = 0x02, // 电池电量同步指令
    poweroff_notify_cmd = 0x03,       // 关机指令
    mic_adta_request_cmd = 0x20,      // MIC数据传输控制指令
    prompt_tone_play_cmd = 0x22,      // 提示音播放指令
    auido_presentations_cmd = 0x23,   // 主板端上行音频播放指令
    mode_switch_cmd = 0x24,           // 通信模式切换指令
    up_data_switch_cmd = 0x25,        // 通信上行是否传输指令,PTT control
    label_data_send_cmd = 0x26,       // 唇图标签传输指令

    img_info_send_cmd = 0x28,               // 图像信息上传指令
    img_data_send_cmd = 0x29,               // 图像数据上传指令
    mode_state_send_cmd = 0x30,             // 模式状态上传指令
    mode_state_send_cmd_to_subplate = 0x32, // 模式状态上传指令到副板
    lip_label_send_cmd = 0x31,              // 单独唇图标签上传指令
    host_main_send_cmd = 0x27,              // 上位机到主板的指令ID

    firmware_version_info_host_cmd = 0x33, // 固件版本信息上传上位机指令ID
    dataset_num_info_send_cmd = 0x34,      // 指令集个数ID

} protocal_list_t;
// 打包数据帧函数
int frame_package_function(protocal_list_t instruct, void *data, unsigned short length);

static unsigned short termios_c_cflag = 0;
static unsigned char real_time_recv_serial_data_flag;
static unsigned char recv_data_display_flag;

static const char *air_pcm_path = "/data/air_audio_data.pcm";
static const char *bone_pcm_path = "/data/bone_audio_data.pcm";
#define PER_AUDIO_FRAME_LEN 480
#define PCM_PATH "/oem/usr/pcm"

typedef struct AudioAnalysis
{
    // 获取音频帧帧头内容
    uint8_t *pdata;
    uint8_t audio_type;
    unsigned short frame_num = 0;
    unsigned short last_frame_num = 0;
    int dif = 0;

    uint8_t *audio_data;
    unsigned int audio_data_length;
    uint8_t air_audio_data[PER_AUDIO_FRAME_LEN] = {0};
    uint8_t bone_audio_data[PER_AUDIO_FRAME_LEN] = {0};
    // 根据音频类型创建音频文件
    FILE *file_air;
    FILE *file_bone;
    const char *air_filename = air_pcm_path;
    const char *bone_filename = bone_pcm_path;
};
static AudioAnalysis audioAnalysis;

static int frame_total_length = 0;
static int dataset_num = 0;

static uint8_t data_buffer[FRAME_BUFFER_LENGTH_MAX] = {0};
static uint8_t save_buffer[FRAME_BUFFER_LENGTH_MAX] = {0};
static unsigned short save_data_length = 0;
static pthread_t serial_read_pthread;    // 串口读取数据线程
static pthread_t frame_analysis_pthread; // 数据帧解析线程
///////////////////////uart_commid/////////////////////////////
static unsigned int validLen = 0; // 循环缓冲区的有效长度
static unsigned int readLen = 0;  // 从循环缓冲区中读取的数据长度

static char viDianTaiCmdFinal[256] = {0}; // 有线模式，电台播放唇语识别语音

int open_serial_port(void);
int set_serial_attribs(void);
void *serial_recv_pthread_function(void *arg);
int serial_send_function(void *data, unsigned short data_len);
int audio_frame_analysis_function(uint8_t *data, unsigned int length);
int frame_analysis_function(uint8_t *data, unsigned int length);
void *frame_analysis_pthread_function(void *arg);
int serial_init(void);
int frame_package_function(protocal_list_t instruct, void *data, unsigned short length);
void query_firmware_info_cmd(int flg);
int ptt_up_data_switch_cmd(int flg);
int lip_label_data_send_cmd(int flg);
int display_mode_switch_cmd(int flg);
int uart_tip_data(int read_data);
int battery_status_notify_cmd_function(int flag, int vol, int cap);
int display_inquire_firmware_info_cmd_function(void);
int command_uart_transform(int id, int flg);
void uart_main_func(int pam1, int pam2, int pam3, int pam4);
void image_info_uart_upload_cmd(int flg);
void image_data_uart_upload_cmd(int pkg_num, int pkg_size, uint8_t *data);
void mode_state_uart_upload_cmd(int stateValue);
void lip_label_uart_upload_cmd(int labelValue);
void host_main_data_trans(void);
vector<uint8_t> convertUint16ToUint8Array(const std::vector<uint16_t> &uint16Data);
vector<uint8_t> readPCMFileToInt8Array(const std::string &filename);
void audio_pcm_uart_upload_func(int label);
// youxian 485 module
void youxian_485_upload(protocal_list_t instruct, void *data, unsigned short length);
void bat_send_func_485(int charge_state, int vol, int cap); // 有线485发送电量
void mode_state_send_func_485(int stateValue);
void lip_label_send_func_485(int label);
void image_data_send_func_485(int pkg_num, int pkg_size, uint8_t *data);
void audio_response_func(uint8_t *data, unsigned int length);
void mode_state_to_subplate(int stateValue);
void poweroff_cmd_send_func(int flg);
void ptt_key_value_send_func_485(int keyValue);
void firmware_version_to_host_send_func(int flg);
void intToUint8Array(int number, uint8_t uint8Array[4]);
void dataset_num_send_func(int flg, int comm);

static int ai_end = 0;     // ai end flag
static int vi_end = 0;     // vi end flag
static int img_up_end = 0; // 图像上传完成标志位
#define TEST_BLOCKED_STATS_FUNC
static mutex mtx_uart;
static unsigned int frameNum = 0;

int InFolder_File_Num(const char *folder_path);
// socket
#define SESSION 10000
#define TYPE 505
#define SEND_BUFFER_SIZE 65536
static char send_buffer[SEND_BUFFER_SIZE];
static int sock_cli = 0;
const char aviCmd[256] = "/data/avi/";
static char viCmdFinal[256] = {0};
static char viCmdFinal_result[256] = {0};
static char aiCmdFinal_air[256] = {0};
static char aiCmdFinal_bone[256] = {0};
static int cnt_ptt = 0;

static int nCount_send = 0;
static RK_S32 sessionNum = 0;
static RK_S32 typeNUm = 0;
/*---20250421 add by mtd:socket communication---*/
#define SEND_BUF_SIZE 65536 // static int SEND_BUF_SIZE = 1024;
static uint8_t public_soc_buffer[SEND_BUF_SIZE] = {0};

static uint8_t scores_buffer[4] = {0};


static int ipSet = 0;
static int timeVal = 0; // 接收来自PC客户端的音频时长
void mic_data_request_function_custom(int totalMilliseconds);
/*----------request data type----------*/
static bool only_video = false;//仅请求视频数据
static bool only_video_model = false;//仅请求视频模型
//仅请求音频模型
static bool only_air_model = false;
static bool only_bone_model = false;
static bool only_air_bone_model=false;
static bool only_video_air_model = false;//请求视频模型+音频模型
static bool only_video_bone_model = false;
static bool only_video_air_bone_model = false;


static bool only_custom_video = false;
static bool finish_send_flag=false;


extern bool ptt_up_flag;

extern bool only_air;
extern bool only_bone;
extern bool only_air_bone;
extern bool only_video_air;
extern bool only_video_bone;
extern bool only_video_air_bone;
extern bool AudioModelInf_or_DataType;
extern bool only_mic_custom_tl;
extern int version;


static int ret = 0;

static long custom_video_total_bytes = 0; // 根据来自客户端的宽度和高度，计算总的字节数
extern int custom_tl; // 自定义音频时长



typedef enum
{
    msg_set_data_timelength = 0x12,  // 设置数据请求长度
    msg_presend_instruct = 0x31,     // 发0x31单模态数据包之前
    msg_sensor_data_instruct = 0x41, // 耳机传感器数据（长数据格式）
    msg_finish_send_instruct = 0x32, // 耳机传输（完全结束）
    msg_power_info_instruct=0x33,//耳机电量信息

    dataType_video = 0x01,
    dataType_air = 0x02,
    dataType_bone = 0x04,
    dataType_air_bone = 0x06,
    dataType_result = 0x08,

} server_client_protocal_list;
void server_client_frame_package_function(server_client_protocal_list instruct, void *data, unsigned short length);
void custom_air_audio_presend_func(int send_data_len);
void custom_audio_presend_func(server_client_protocal_list instruct,int send_data_len);

void custom_video_presend_func(int width, int height,int data_len);
void results_presend_func(void);
void results_send_func(int results);
void results_scores_send_func(int results,int scores);

void data_type_finish_send_func(server_client_protocal_list instruct);

static FILE *socAiFp_air = NULL;
void custom_air_audio_send_func();

#define FLOW_VIDEO_CUSTOM_RS 1 // 流式视频：自定义分辨率

// 数据队列
static queue<std::vector<uint8_t>> dataQueue_video;
static mutex mtx_soc_video;
#define SEND_FRAME_HEAD_LEN 12

extern std::mutex mtx_soc_sendData;
void power_info_send_func(int powerValue);


//控制socket_air数据发送
static condition_variable cv_mic_socket_air; // 条件变量
static bool start_mic_socket_air = false;
double getTimeInMilliseconds();



#endif
